/*
  ArtToSpr Artworks/Draw to Sprite convertor
  Copyright (c) 1998 Tony Houghton

  This source is distributed under the GPL. Please see the file
  "COPYING" for details.
*/

#include "osfile.h"

#include "flex.h"

#include "artworks.h"
#include "draw.h"
#include "err.h"
#include "msgtrans.h"
#include "picture.h"
#include "rescodes.h"

bool picture_load(picture *result, const char *filename,
	int *pft, int *pfs, char *utc)
{
  int size;
  bits ftype;
  fileswitch_object_type otype;
  bits load, exec;

  if (E(xosfile_read_stamped(filename, &otype, &load, &exec, &size, 0, &ftype)))
    return false;
  if (otype != 1 || !size)
  {
    err_report(0, msgs_plookup("NoFile", filename, 0, 0, 0));
    return false;
  }
  if (!flex_alloc(&result->data, size))
  {
    result->data = 0;
    return false;
  }
  if (E(xosfile_load_stamped(filename, result->data,
  	NULL, NULL, NULL, NULL, NULL)))
  {
    flex_free(&result->data);
    result->data = 0;
    return false;
  }
  switch (ftype)
  {
    case 0xd94:
      result->render = artworks_render;
      result->bounds = artworks_bbox;
      if (E(artworks_prepare(result)))
      {
        flex_free(&result->data);
        result->data = 0;
        return false;
      }
      break;
    default:
      result->render = draw_render;
      result->bounds = draw_bbox;
      break;
  }
  if (pft) *pft = (int) ftype;
  if (pfs) *pfs = size;
  if (utc)
  {
    *((bits *) utc) = exec;
    utc[4] = load & 0xff;
  }
  return true;
}

void picture_free(picture *pic)
{
  if (!pic->data)
    return;
  flex_free(&pic->data);
  pic->data = 0;
}

bool picture_sprite_size(picture *pic, picture_matrix *trfm,
	int margin, int *width, int *height)
{
  BBox dbounds;

  trfm->e = trfm->f = 0;
  if (E(pic->bounds(pic, trfm, &dbounds)))
    return false;
  *width = ((dbounds.xmax - dbounds.xmin) >> 8) + 2 * margin;
  *height = ((dbounds.ymax - dbounds.ymin) >> 8) + 2 * margin;
  trfm->e = (margin << 8) - dbounds.xmin;
  trfm->f = (margin << 8) - dbounds.ymin;
  return true;
}

bool picture_scale_to_fit(picture *pic, picture_matrix *trfm,
	int margin, int *width, int *height, bool preserve_aspect, int aspect)
{
  int w, h;
  double scx, scy;

  /* First find necessary scale factors */
  if (!picture_sprite_size(pic, trfm, 0, &w, &h))
    return false;
  scx = (double) ((int) (*width - 2 * margin)) / (double) w;
  scy = (double) ((int) (*height - 2 * margin)) / (double) h;
  if (preserve_aspect)
  {
    if (scx > scy)
      scx = scy;
    else
      scy = scx;
  }
  trfm->a = (int) ((double) trfm->a * scx);
  trfm->c = (int) ((double) trfm->c * scx);
  trfm->b = (int) ((double) trfm->b * scy);
  trfm->d = (int) ((double) trfm->d * scy);
  /* Call again to get translation */
  if (!picture_sprite_size(pic, trfm, margin, &w, &h))
    return false;
  if (preserve_aspect)
  {
    switch (aspect)
    {
      case gadget_TRIM:
        *width = w;
        *height = h;
        break;
      case gadget_CENTRE:
        trfm->e += ((*width - w) / 2) << 8;
        trfm->f += ((*height - h) / 2) << 8;
    }
  }
  return true;
}

void picture_init(picture *pic)
{
  pic->data = 0;
}
